<?php

namespace app\api\controller\v50;

use app\aliyun\controller\AliyunFilterWordV2;
use app\api\controller\v2\Auth;
use app\common\cachemodel\name_analyze\Zl9NameAnalyzeCreateNameRecord;
use app\common\cachemodel\name_analyze\Zl9NameAnalyzeRecodeBack;
use app\common\cachemodel\name_analyze\Zl9NameAnalyzeRecord;
use app\common\lib\horoscope\Horoscope;
use app\common\lib\Util;
use app\common\model\Recode;
use app\common\service\ChatParse;
use think\Env;

class UserNameAnalyze extends Auth
{
    /**
     * 提交 名字评分分析
     * @return \think\response\Json
     * @throws \Exception
     */
    public function analyzeSubmit()
    {
        $name1 = input('name1/s', '');
        $name2 = input('name2/s', '');
        $rid = input('rid/d', 0);
        if (empty($name1))
        {
            return show(config('code.error'), '请输入姓氏');
        }
        if (empty($name2))
        {
            return show(config('code.error'), '请输入名字');
        }
        if (mb_strlen($name1) > 2)
        {
            return show(config('code.error'), '姓氏最多两个字');
        }
        if (mb_strlen($name2) > 2)
        {
            return show(config('code.error'), '名字最多两个字');
        }
        $resName = trim(sprintf('%s%s', $name1, $name2));
        if (preg_match('/^[\x{4e00}-\x{9fa5}]+$/u', $resName) !== 1)
        {
            return show(config('code.error'), '输入的姓名只支持中文');
        }
        if (!$rid)
        {
            return show(config('code.error'), '请选择档案');
        }
        $recodeInfo = (new Recode())->getRecode(['id' => $rid]);
        if (!$recodeInfo || $recodeInfo['uid'] != $this->user['id'])
        {
            return show(config('code.error'), '服务异常，档案不存在～');
        }

        $aliRes = AliyunFilterWordV2::checkAIText($name1 . $name2, 'llm_query_moderation_03');
        if ($aliRes['status'] === false)
        {
            return show(config('code.error'), '检测到敏感内容');
        }

        $backRecord = [
            'rid' => $rid,
            'recode_info' => $recodeInfo,
        ];
        //  备份档案
        $backRid = (new Zl9NameAnalyzeRecodeBack())->SaveData($backRecord);
        $resNameArr = mb_str_split($resName);
        $pinYinData = ChatParse::getNamePinyin($resName);
        if (!$pinYinData['success'] || count($pinYinData['data']) !== count($resNameArr))
        {
            return show(config('code.error'), '服务异常，请稍后再试～');
        }
        $nameDatas = [];
        foreach ($pinYinData['data'] as $k => $v)
        {
            $nameDatas[] = [
                'pinyin' => $v,
                'text' => $resNameArr[$k],
            ];
        }
        $content = [
            'names' => $nameDatas,
            'birth_time' => sprintf('%d年%02d月%02d日 %02d:%02d', $recodeInfo['year'], $recodeInfo['month'], $recodeInfo['day'], $recodeInfo['hour'], $recodeInfo['minute']),
        ];
        $insertData = [
            'uid' => $this->user['id'],
            'rid' => $rid,
            'surname' => $name1,
            'name' => $name2,
            'status' => 0,
            'content' => $content,
            'back_rid' => $backRid,
            'create_time' => $this->request->time(),
        ];
        $resId = (new Zl9NameAnalyzeRecord())->SaveData($insertData);
        if ($resId)
        {
            return show(config('code.success'), '请求成功', ['id' => $resId]);
        }
        return show(config('code.error'), '服务异常，请稍后再试～');
    }

    /**
     * 获取 名字评分分析结果
     * @return \think\response\Json
     * @throws \Exception
     */
    public function getAnalyzeResult()
    {
        $id = input('id/d', 0);
        if (!$id)
        {
            return show(config('code.error'), '请求异常，请刷新后重试～');
        }
        $zl9NameAnalyzeRecordModel = new Zl9NameAnalyzeRecord();
        $data = $zl9NameAnalyzeRecordModel->getInfoById($id);
        if (!$data || $data['uid'] != $this->user['id'])
        {
            return show(config('code.error'), '服务异常，数据不存在～');
        }
        if (in_array($data['status'], [1, 3], true) && $this->request->time() - $data['start_time'] > 300)
        {   // 计算中 或 计算失败
            $zl9NameAnalyzeRecordModel->UpdateData($id, ['status' => 1, 'start_time' => $this->request->time(), 'update_time' => $this->request->time()]);
            Util::queuePush('horoscope_name_analyze', ['id' => $id]);
        }

        $resData = $zl9NameAnalyzeRecordModel->dataResert($data);

        return show(config('code.success'), '请求成功', $resData);
    }

    /**
     * 获取 名字五行分析结果流
     * @return \think\response\Json
     * @throws \Exception
     */
    public function getAnalyzeWuxingResultStream()
    {
        $id = input('id/d', 0);
        if (!$id)
        {
            echo '';
            return;
        }
        $zl9NameAnalyzeRecordModel = new Zl9NameAnalyzeRecord();
        $data = $zl9NameAnalyzeRecordModel->getInfoById($id);
        if (!$data || $data['uid'] != $this->user['id'])
        {
            echo '';
            return;
        }
        if (isset($data['wx_analysis']) && $data['wx_analysis'])
        {
            echo $data['wx_analysis'];
            return;
        }
        $recodeInfo = (new Zl9NameAnalyzeRecodeBack())->getInfoById($data['back_rid']);
        $baziData = Horoscope::getInstance([
            'recode' => $recodeInfo['recode_info'],
            'time_start' => 23,
            'time_type' => 0,
//            'advance' => [
//                'year' => date('Y', $timestamp) * 1,
//                'month' => date('m', $timestamp) * 1,
//                'day' => date('d', $timestamp) * 1,
//                'hour' => date('H', $timestamp) * 1,
//                'minute' => date('i', $timestamp) * 1,
//                'timezone' => 8,
//                'is_summer' => 0,
//            ]
        ])->getUserDataForAI();
        $params = [
            'uid' => $this->user['id'],
            'sur_name' => $data['surname'],   // 姓氏
            'name' => $data['name'], // 名字
            'calendar_date' => $data['content']['birth_time'],  // 出生日期
            'bazi' => $baziData['bazi'], // 八字，例如：年柱(乙亥) 月柱(癸水) 日柱(己酉) 时柱(庚午)
            'joyful_god' => $baziData['joyful_god'],    // 最大用神
            'pattern' => $baziData['pattern'],  //  格局，例如：['此处为内格局','此处为外格局']，如没有格局则为空字符串，如果包含多个用中文逗号拼接
            'chinese_calendar_date' => $baziData['chinese_calendar_date'],  //  农历日期例：乙亥年六月二十 午时
            'use_zhipu_ali_moonshot_type' => 3, //  使用模型类型 0=>智谱 1=>千问 2=>moonshot 3=>根据效果优先级处理顺序
        ];
        $queryStr = ChatParse::getNameAnalyzeWuxingStreamData($params);
        if ($queryStr)
        {
            if (strpos($queryStr, 'θ') !== false)
            {
                $queryStr = '服务异常，分析失败';
            }
            $zl9NameAnalyzeRecordModel->UpdateData($id, ['wx_analysis' => $queryStr, 'update_time' => $this->request->time()]);
        }
        return;
    }

    /**
     * 获取评分｜起名记录
     * @return \think\response\Json
     */
    public function getRecordList()
    {
        $type = input('type/d', 1);
        $page = input('page/d', 1);
        if (!in_array($type, [1, 2], true))
        {
            return show(config('code.error'), '请求异常，请刷新后重试～');
        }
        if ($page < 1)
        {
            $page = 1;
        }
        if ($type === 1)
        {
            $resData = (new Zl9NameAnalyzeRecord())->getPageListData($this->user['id'], $page);
        } else
        {
            $resData = (new Zl9NameAnalyzeCreateNameRecord())->getPageListData($this->user['id'], $page);
        }

        return show(config('code.success'), '请求成功', $resData);
    }

    /**
     * 个人取名
     * @return \think\response\Json
     * @throws \Exception
     */
    public function createNamePersonal()
    {
        $rid = input('rid/d', 0);   //  档案ID
        $sex = input('sex/d', 0);   //  性别 1=>男 2=>女
        $familyName = input('family_name/s', '');   //  姓氏
        $num = input('num/d', 0);   //  几个字  【 2 ｜ 3 ｜ 4 】
        $type = input('type/d', 0); //  0=>不设置 1=>设置中位字 2=>设置末尾字
        $text = input('text/s', '');    //  设置的 【 中位字 ｜ 末尾字 】
        $remark = input('remark/s', '');    //  特殊要求
        $isBorn = input('is_born/d', 0);    //  是否出生 1=>已出生 2=>未出生
        if (!in_array($sex, [1, 2], true))
        {
            return show(config('code.error'), '请选择性别！');
        }
        if (!in_array($num, [2, 3, 4], true))
        {
            return show(config('code.error'), '请选择字数！');
        }
        if ($num === 2)
        {
            $type = 0;
            $text = '';
        }
        if (!in_array($type, [0, 1, 2], true))
        {
            return show(config('code.error'), '请求异常，请重新再试～');
        }
        if (!in_array($isBorn, [1, 2], true))
        {
            return show(config('code.error'), '请选择是否出生！');
        }
        if ($type > 0 && empty($text))
        {
            return show(config('code.error'), '请输入设置字！');
        }
        if ($type > 0 && mb_strlen($text) !== 1)
        {
            return show(config('code.error'), '设置字只能设置一个字～');
        }
        if (mb_strlen($remark) > 80)
        {
            return show(config('code.error'), '特殊要求字数不能超过80字～');
        }
        if (empty($familyName))
        {
            return show(config('code.error'), '请输入姓氏～');
        }
        if (mb_strlen($familyName) > 2)
        {
            return show(config('code.error'), '姓氏字数不能超过2个字～');
        }
        if (empty($rid))
        {
            return show(config('code.error'), '请选择档案～');
        }
        $recodeInfo = (new Recode())->getRecode(['id' => $rid]);
        if (!$recodeInfo || $recodeInfo['uid'] != $this->user['id'])
        {
            return show(config('code.error'), '服务异常，档案不存在～');
        }

        $aliRes = AliyunFilterWordV2::checkAIText($familyName . $text . $remark, 'llm_query_moderation_03');
        if ($aliRes['status'] === false)
        {
            return show(config('code.error'), '检测到敏感内容');
        }

        $backRecord = [
            'rid' => $rid,
            'recode_info' => $recodeInfo,
        ];
        //  备份档案
        $backRid = (new Zl9NameAnalyzeRecodeBack())->SaveData($backRecord);
        $paramData = [
            'rid' => $rid,
            'back_rid' => $backRid,
            'sex' => $sex,
            'surname' => $familyName,
            'num' => $num,
            'type' => $type,
            'text' => $text,
            'remark' => $remark,
            'is_born' => $isBorn,
            'recode_birth_date' => sprintf('%d年%02d月%02d日', $recodeInfo['year'], $recodeInfo['month'], $recodeInfo['day']),  //  档案出生日期
            'recode_birth_time' => sprintf('%02d:%02d', $recodeInfo['hour'], $recodeInfo['minute']),  //  档案出生时间
            'recode_name' => $recodeInfo['name'],    //  档案名字
        ];
        // 获取 八字信息
        $baziData = Horoscope::getInstance([
            'recode' => $recodeInfo,
            'time_start' => 23,
            'time_type' => 0,
        ])->getUserDataForQiming([$recodeInfo]);
        $content = [
            'wuxing_data' => $baziData[0],
        ];
        $insertData = [
            'uid' => $this->user['id'],
            'type' => 1,
            'params' => $paramData,
            'content' => $content,
            'create_time' => $this->request->time(),
            'update_time' => $this->request->time(),
        ];
        $id = (new Zl9NameAnalyzeCreateNameRecord())->SaveData($insertData);
        if ($id)
        {
            return show(config('code.success'), '请求成功', ['id' => $id]);
        } else
        {
            return show(config('code.error'), '服务异常，请重试～');
        }
    }

    /**
     * 公司取名
     * @return \think\response\Json
     * @throws \Exception
     */
    public function createNameCompany()
    {
        $recodes = input('recodes/s', '');  //  创始人档案信息 JSON 格式
        $companyRid = input('company_rid/d', 0);    //  公司档案ID
        $business = input('business/s', '');    //  主营业务
        $remark = input('remark/s', '');    //  特殊要求
        $recodeModel = new Recode();
        if (empty($recodes))
        {
            return show(config('code.error'), '请选择创始人档案信息～');
        }
        $recodesArr = json_decode($recodes, true);
        if (!$recodesArr)
        {
            return show(config('code.error'), '创始人档案信息错误～');
        }
        if (count($recodesArr) > 3)
        {
            return show(config('code.error'), '创始人信息不能超过3个～');
        }
        $backRecodeList = [];
        $rname = '';
        foreach ($recodesArr as $item)
        {
            if (!isset($item['rid'], $item['name']) || count($item) > 2)
            {
                return show(config('code.error'), '创始人信息错误～');
            }
            if (empty($item['name']))
            {
                return show(config('code.error'), '创始人姓名不能为空～');
            }
            if (mb_strlen($item['name']) > 10)
            {
                return show(config('code.error'), '创始人姓名字数不能超过10个字～');
            }
            if (empty($item['rid']))
            {
                return show(config('code.error'), '创始人档案信息异常～');
            }
            $recodeInfoItem = $recodeModel->getRecode(['id' => $item['rid']]);
            if (!$recodeInfoItem || $recodeInfoItem['uid'] != $this->user['id'])
            {
                return show(config('code.error'), '服务异常，创始人档案不存在～');
            }
            $backRecodeList[$item['rid']] = [
                'rid' => $item['rid'],
                'recode_info' => $recodeInfoItem,
            ];
            $rname .= $item['name'];
        }
        if (empty($companyRid))
        {
            return show(config('code.error'), '请选择公司档案信息～');
        }
        $companyRecodeInfo = $recodeModel->getRecode(['id' => $companyRid]);
        if (!$companyRecodeInfo || $companyRecodeInfo['uid'] != $this->user['id'])
        {
            return show(config('code.error'), '服务异常，公司档案不存在～');
        }
        $backRecodeList[$companyRid] = [
            'rid' => $companyRid,
            'recode_info' => $companyRecodeInfo,
        ];
        if (mb_strlen($business) < 6)
        {
            return show(config('code.error'), '主营业务字数不能少于6字～');
        }
        if (mb_strlen($business) > 50)
        {
            return show(config('code.error'), '主营业务字数不能超过50字～');
        }
        if (mb_strlen($remark) < 6)
        {
            return show(config('code.error'), '特殊要求字数不能少于6字～');
        }
        if (mb_strlen($remark) > 80)
        {
            return show(config('code.error'), '特殊要求字数不能超过80字～');
        }

        $aliRes = AliyunFilterWordV2::checkAIText($rname . $business . $remark, 'llm_query_moderation_03');
        if ($aliRes['status'] === false)
        {
            return show(config('code.error'), '检测到敏感内容');
        }

        $backRecodeIdArr = [];
        $zl9NameAnalyzeRecodeBackModel = new Zl9NameAnalyzeRecodeBack();
        foreach ($backRecodeList as $rid => $backRecodeItem)
        {
            $backRid = $zl9NameAnalyzeRecodeBackModel->SaveData($backRecodeItem);
            $backRecodeIdArr[$rid] = $backRid;
        }
        $originatorData = [];
        foreach ($recodesArr as $item)
        {
            $recodeInfo = $backRecodeList[$item['rid']]['recode_info'];
            $originatorData[] = [
                'name' => $item['name'],
                'rid' => (int)$item['rid'],
                'back_rid' => $backRecodeIdArr[$item['rid']],
                'birth_date' => sprintf('%d年%02d月%02d日', $recodeInfo['year'], $recodeInfo['month'], $recodeInfo['day']),
                'birth_time' => sprintf('%02d:%02d', $recodeInfo['hour'], $recodeInfo['minute']),
            ];
        }
        $paramData = [
            'originator_data' => $originatorData,   // 创始人信息
            'company_rid' => $companyRid,   // 公司信息档案ID
            'back_company_rid' => $backRecodeIdArr[$companyRid],    //  公司信息档案备份ID
            'c_birth_date' => sprintf('%d年%02d月%02d日', $companyRecodeInfo['year'], $companyRecodeInfo['month'], $companyRecodeInfo['day']),        //  公司的开业时间 日期
            'c_birth_time' => sprintf('%02d:%02d', $companyRecodeInfo['hour'], $companyRecodeInfo['minute']),        //  公司的开业时间 时间点
            'business' => $business,
            'remark' => $remark,
        ];
        $resRecodeList = array_column($backRecodeList, 'recode_info');
        // 获取 八字信息
        $baziData = Horoscope::getInstance([
            'recode' => $resRecodeList[0],
            'time_start' => 23,
            'time_type' => 0,
        ])->getUserDataForQiming($resRecodeList);
        $wuxingData = [];
        foreach ($baziData as $k => $baziItem)
        {
            $wuxingData[$resRecodeList[$k]['id']] = $baziItem;
        }
        $content = [
            'wuxing_data' => $wuxingData,
        ];
        $insertData = [
            'uid' => $this->user['id'],
            'type' => 2,    //  1=>个人起名 2=>公司起名
            'params' => $paramData,
            'content' => $content,
            'create_time' => $this->request->time(),
            'update_time' => $this->request->time(),
        ];
        $id = (new Zl9NameAnalyzeCreateNameRecord())->SaveData($insertData);
        if ($id)
        {
            return show(config('code.success'), '请求成功', ['id' => $id]);
        } else
        {
            return show(config('code.error'), '服务异常，请重试～');
        }
    }

    /**
     * 获取取名结果
     * @return \think\response\Json
     * @throws \Exception
     */
    public function getCreateNameDetail()
    {
        $id = input('id/d', 0);
        $createNameRecordModel = new Zl9NameAnalyzeCreateNameRecord();

        $data = $createNameRecordModel->getInfoById($id);
        if (!$data || $data['uid'] != $this->user['id'] || $data['status'] === 0)
        {
            return show(config('code.error'), '服务异常，数据不存在～');
        }
        if ($data['type'] === 1)
        {
            $resData = $createNameRecordModel->dataResertPersonal($data);
        } else
        {
            $resData = $createNameRecordModel->dataResertCompany($data);
        }

        return show(config('code.success'), '请求成功', $resData);
    }
}
